<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <h3>let a=a;在运行时出现什么，为什么</h3>
    <p>Uncaught ReferenceError: a is not defined</p>
    <p>分为2个阶段：</p>
    <p>在预编译阶段，将let声明的变量放到暂存性死区TDZ中 TDZ=[a]</p>
    <p>当let声明语句结束之后，这里的结束指的是，当let a = a执行完事后，会把a从TDZ拿出来。</p>
    <p>但是let a = a执行的时候，右侧赋值的a还在TDZ中，所以报错。也就是未声明就使用的错误。</p>
    <p>所以，大家在使用let变量时，切记一定要先声明后使用</p>
    <p>ES6 let与块级作用域</p>
    <p>块级作用域</p>
    <p>什么叫块级作用域？除了对象字面量上的大括号 都叫块级作用域</p>
    <p>例：{</p>
    <p>//产生TDZ[]</p>
    <p>var a=10;</p>
    <p>let b=100;</p>
    <p>//TDZ结束</p>
    <p>}
        <p>console.log(a); 10</p>
        <p>console.log(b); 报错</p>
        <p>for循环也是</p>
        <p>let 具有识别块级作用域的能力</p>
        <p>不存在变量提升</p>
        <p>console.log(str); 报错 typeof也不好使</p>
        <p>let str=10;</p>
        <p>在预编译过程中 let 暂时性死区（TDZ tempral dead zone）</p>
        <p>js扫码的时候</p>
        <p>var整体提升</p>
        <p>let a=1; let a放入一个暂时性死区 ，如果使用变量的时候 在TDZ中发现变量在里面就报错</p>
        <p>当执行到let a =1；释放出来</p>
        <p>统领当前作用域</p>
        <p>先定义 再使用</p>
        <p>不能重复定义</p>
        <p>let a = 'xn'</p>
        <p>let a = 'xx' 报错 已经被定义</p>
        <script>
            let a = a;
            console.log(a);
        </script>
</body>

</html>